package com.xxl.job.executor.service.jobhandler;

import com.alibaba.fastjson.JSONObject;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.executor.dao.QxWeatherMapper;
import com.xxl.job.executor.model.QxWeather;
import com.xxl.job.executor.utils.CmUtil;
import com.xxl.job.executor.utils.ConstUtil;
import org.htmlparser.Node;
import org.htmlparser.NodeFilter;
import org.htmlparser.Parser;
import org.htmlparser.filters.StringFilter;
import org.htmlparser.util.NodeList;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.net.InetSocketAddress;
import java.net.Proxy;
import java.text.SimpleDateFormat;
import java.util.*;

/*
   "天气数据（过去24小时整点）抓取"
 */

@Component
public class WeatherDataForPast24HourTask {


    private static Logger logger = LoggerFactory.getLogger(WeatherDataForPast24HourTask.class);

    private String taskContents;
    @Autowired
    private ConstUtil constUtil;
    @Autowired
    private QxWeatherMapper qxWeatherMapper;

    @XxlJob(value = "WeatherDataForPast24HourTask",init = "init", destroy = "destroy")
    public ReturnT<String> WeatherDataForPast24HourTask(String param) throws Exception {

//
//        if (constUtil == null) {
//            constUtil = SpringContextHolder.getBean(ConstUtil.class);
//        }
//        if (qxWeatherMapper == null) {
//            qxWeatherMapper = SpringContextHolder.getBean(QxWeatherMapper.class);
//        }
        String weatherUrl = "";
        // 各区市天气数据网址后缀
        HashMap<String,String> district = new HashMap<>();
        district.put(constUtil.distName,constUtil.distId);
//        district.put("崂山","101120202");
//        district.put("市南","101120203");
//        district.put("即墨","101120204");
//        district.put("胶州","101120205");
//        district.put("黄岛","101120206");
//        district.put("莱西","101120207");
//        district.put("平度","101120208");
//        district.put("市北","101120209");
//        district.put("李沧","101120210");
//        district.put("城阳","101120211");
//          district.put("乌鲁木齐","101130101");
        // 青岛市天气数据网址前缀
        String weatherBaseUrl = constUtil.weatherBaseUrl1;
        // 修改 无效Map Iterator
        Iterator<Map.Entry<String, String>> iterator  = district.entrySet().iterator();
        Map.Entry<String, String> entry = null;
        // 循环获取各区市天气数据
        while (iterator.hasNext()) {
            entry = iterator.next();
            String key = entry.getKey();
            weatherUrl = weatherBaseUrl+district.get(key)+".shtml";
            // 获取html文本内容
            Document doc = getHtml(weatherUrl, constUtil);
            if(doc == null) {
                System.out.println("null");
            };
            Parser parser = Parser.createParser(doc.toString(), "utf-8");
            try{
                // 获取过去24小时整点天气数据
                NodeFilter filter = new StringFilter("var observe24h_data");
                NodeList nodes = parser.extractAllNodesThatMatch(filter);
                if(nodes!=null) {
                    for (int i = 0; i < nodes.size(); i++) {
                        Node textnode = (Node) nodes.elementAt(i);
                        String qxWeatherRaw = textnode.getText().substring(22);
                        String qxWeatherData = qxWeatherRaw.substring(0,qxWeatherRaw.length()-2);
                        JSONObject jsonObject = JSONObject.parseObject(qxWeatherData);
                        JSONObject od = jsonObject.getJSONObject("od");
                        // 获取当天日期
                        String nowDate = od.getString("od0").substring(0,4)
                                +"-"+od.getString("od0").substring(4,6)+"-"
                                +od.getString("od0").substring(6,8);
                        String constDate = nowDate;
//                        // 获取城市
////                        String city = od.getString("od1");

                        // 获取过去24小时整点天气情况信息
//                        JSONArray jsonArray = od.getJSONArray("od2");
//                        jsonArray.toJavaList(Object.class);
                        List<HashMap> list = JSONObject.parseArray(od.getString("od2"),HashMap.class);
                        if(list == null)    list = new ArrayList<>();
                        int number = 0;
                        // 日期判断标志
                        int flag = 26 ;
                        for(Object obj :list){
                            String urbanDistrict = key;
                            String wKind = "past24hour";
                            Map<String,Object> map = (HashMap<String,Object>)obj;
                            QxWeather qxWeather;
                            number++;
                            // 获取整点时间
                            String wTime = map.get("od21").toString();
                            if (wTime.equals("00")){
                                flag = number;
                            }
                            if(number>flag){
                                // 当天日期的前一天
                                SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd");
                                Date date = df.parse(constDate);
                                nowDate = df.format(new Date(date.getTime() - (long)1 * 24 * 60 * 60 * 1000));
                            }
                            // 获取温度
                            String temp = map.get("od22").toString();
                            // 获取风向
                            String windDirection = map.get("od24").toString();
                            // 获取风速
                            String windSpeed = map.get("od25").toString();
                            // 获取降水量
                            String rainfall = map.get("od26").toString();
                            // 获取湿度
                            String humidity = map.get("od27").toString();
                            if (!(humidity.equals("null")||humidity.equals(""))) {
                                humidity = humidity+"%";
                            }
                            String queryDate = nowDate;
                            String forWtime = (Integer.valueOf(wTime)-1)+"";
                            if (forWtime.equals("-1")) {
                                SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
                                Date date = df.parse(nowDate);
                                queryDate = df.format(new Date(date.getTime() - (long)1 * 24 * 60 * 60 * 1000));
                                forWtime = "23";
                            }
                            qxWeather = qxWeatherMapper.selectPast24hour(queryDate,forWtime,wKind,urbanDistrict);
                            if (qxWeather!=null) {
                                if (temp.equals("null")||temp.equals("")) {
                                    temp = qxWeather.getTemp();
                                }
                                if(windDirection.equals("暂无风向")||windDirection.equals("")) {
                                    windDirection = qxWeather.getWindDirection();
                                }
                                if (windSpeed.equals("null")||windSpeed.equals("")) {
                                    windSpeed= qxWeather.getWindSpeed();
                                }
                                if (rainfall.equals("null")||rainfall.equals("")) {
                                    rainfall = qxWeather.getRainfall();
                                }
                                if (humidity.equals("null")||humidity.equals("")) {
                                    humidity = qxWeather.getHumidity();
                                }
                            }
                            ArrayList<String>weatherList = new ArrayList<>();
                            weatherList.add(windDirection);
                            weatherList.add(windSpeed);
                            weatherList.add(temp);
                            weatherList.add(humidity);
                            weatherList.add(rainfall);
                            // 查询天气数据（过去24小时）是否存在
                            qxWeather = qxWeatherMapper.selectPast24hour(nowDate,wTime,wKind,urbanDistrict);
                            // 判断当前整点时间天气信息是否存在
                            if (qxWeather == null) {
                                try {
                                    // 不存在
                                    qxWeather = new QxWeather();
                                    // 插入一条新的天气数据到数据库
                                    qxWeather.setId(CmUtil.getUUID());
                                    qxWeather.setCreateTime(CmUtil.date2db(null));
                                    // 整点时间
                                    qxWeather.setWtime(wTime);
                                    //                                    // 日期
                                    qxWeather.setWdate(nowDate);
//                                    // 序号(时段)(0~24；0表示今天最近整点时间，24表示昨天相对应的整点时间)
//                                    qxWeather.setPeriod((number++)+"");
                                    // 城市
                                    qxWeather.setDist(key);
                                    // 温度
                                    qxWeather.setTemp(temp);
                                    // 风向
                                    qxWeather.setWindDirection(windDirection);
                                    // 风速
                                    qxWeather.setWindSpeed(windSpeed);
                                    // 降水量
                                    qxWeather.setRainfall(rainfall);
                                    // 相对湿度
                                    qxWeather.setHumidity(humidity);
                                    // 数据类型（past24Hour）
                                    qxWeather.setWkind("past24hour");
                                    qxWeatherMapper.insertSelective(qxWeather);
                                    this.taskContents = "插入"+key+nowDate+" "+wTime+"时"+"天气数据成功！";
                                }catch (Exception e){
                                    e.printStackTrace();
                                    this.taskContents = "插入"+key+nowDate+" "+wTime+"时"+"天气数据异常！";
                                }
                            }else if(!qxWeather.toString().equals(weatherList.toString())){
                                // 更新已有整点天气数据
                                try {
                                    // 温度
                                    qxWeather.setTemp(temp);
                                    // 风向
                                    qxWeather.setWindDirection(windDirection);
                                    // 风速
                                    qxWeather.setWindSpeed(windSpeed);
                                    // 降水量
                                    qxWeather.setRainfall(rainfall);
                                    // 相对湿度
                                    qxWeather.setHumidity(humidity);
                                    qxWeatherMapper.updateByPrimaryKeySelective(qxWeather);
                                    this.taskContents = "更新"+key+nowDate+" "+wTime+"时"+"天气数据成功！";
                                }catch (Exception e){
                                    e.printStackTrace();
                                    this.taskContents = "更新"+key+nowDate+" "+wTime+"时"+"天气数据异常！";
                                }
                            }
                        }
                    }
                }
                this.taskContents = "请求"+key+"天气数据异常！";
            }catch (Exception e){
                e.printStackTrace();
                this.taskContents = "请求"+key+"天气数据异常！";
            }
        }
        return ReturnT.SUCCESS;
    }

    /**
     * 获取HTML内容
     *
     * @param url
     * @return
     */
    public static Document getHtml(String url, ConstUtil constUtil) {
        Document doc = null;
        try {
            if (constUtil.useProxy) {
                // 设置代理
                Proxy proxy = new Proxy(Proxy.Type.DIRECT.HTTP, new InetSocketAddress(constUtil.proxyId, constUtil.proxyPort));
                doc = Jsoup.connect(url)
                        .proxy(proxy)
                        .userAgent("Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; MALC)")
                        .timeout(999999999)
                        .header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
                        .header("Accept-Encoding", "gzip, deflate")
                        .header("Accept-Language", "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3")
                        .header("Connection", "keep-alive")
                        //是忽略请求类型
                        .ignoreContentType(true)
                        .get();
            } else {
                doc = Jsoup.connect(url)
                        .userAgent("Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; MALC)")
                        .timeout(999999999)
                        .header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
                        .header("Accept-Encoding", "gzip, deflate")
                        .header("Accept-Language", "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3")
                        .header("Connection", "keep-alive")
                        //是忽略请求类型
                        .ignoreContentType(true)
                        .get();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return doc;
    }

    public void init(){
        logger.info("init");
    }
    public void destroy(){
        logger.info("destory");
    }

}
